/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "ScriptFactory.h"
#include <stddef.h>

ScriptFactory                * ScriptFactory::_instance         = NULL;
std::map<std::string, void*> * ScriptFactory::_creationHandlers = ScriptFactory::createHandlersMap();

ScriptFactory::ScriptFactory()
{
}

ScriptFactory::ScriptFactory(const ScriptFactory & other)
{
}

ScriptFactory::~ScriptFactory()
{
}

ScriptFactory & ScriptFactory::operator=(const ScriptFactory & other)
{
	return *this;
}

ScriptFactory * ScriptFactory::instance()
{
	if(_instance == NULL)
		_instance = new ScriptFactory();
	
	return _instance;
}

std::map<std::string, void*> * ScriptFactory::createHandlersMap()
{
	static std::map<std::string, void*> * handlersMap = new std::map<std::string, void*>();
	
	return handlersMap;
}

void ScriptFactory::addScriptType(const char * name, IScript * (*func)())
{
	_creationHandlers = ScriptFactory::createHandlersMap();
	(*_creationHandlers)[name] = (void*)func;
}

IScript * ScriptFactory::scriptFromFile(const char * type, const char * path)
{
	// check for creation handler for this type
	if(_creationHandlers->find(type) == _creationHandlers->end())
	{
		printf("Unable to find creator for script type '%s'\n", type);
		return NULL;
	}
	
	// create new script object
	IScript * newScript = ((IScript*(*)())(*_creationHandlers)[type])();
	
	// check result
	if(newScript == NULL)
		return NULL;
	
	// load script from file
	if(!newScript->createFromFile(path))
	{
		newScript->release();
		return NULL;
	}
	
	// return new script
	return newScript;
}

IScript * ScriptFactory::scriptFromString(const char * type, const char * code)
{
	// check for creation handler for this type
	if(_creationHandlers->find(type) == _creationHandlers->end())
	{
		printf("Unable to find creator for script type '%s'\n", type);
		return NULL;
	}
	
	// create new script object
	IScript * newScript = ((IScript*(*)())(*_creationHandlers)[type])();
	
	// check result
	if(newScript == NULL)
		return NULL;
	
	// load script from file
	if(!newScript->createFromString(code))
	{
		newScript->release();
		return NULL;
	}
	
	// return new script
	return newScript;
}